#pragma once 
#include <iostream>
#include <cstdint>
#include "Commn.hpp"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "Log.hpp"
#include "InetAddr.hpp"
#include <string>
using namespace LogModule;
int gport = 8888;
class ServerTcp
{
public:
    ServerTcp(uint16_t port = gport)
        :_port(port)
     {}
    void Init()
    {
        _listenfd = ::socket(AF_INET,SOCK_STREAM,0); //流式套接字
        if (_listenfd < 0) 
        {
            Die(SOCKET_ERROR);
        }
        std::cout << "listen success, listenfd is " << _listenfd << std::endl;
        sockaddr_in local;
        local.sin_family = AF_INET;
        local.sin_port = ::htons(_port);
        local.sin_addr.s_addr = INADDR_ANY;
        socklen_t len = sizeof(local);
        int n = ::bind(_listenfd,CONV(&local),len);
        if (n < 0) 
        {
            Die(BIND_ERROR);
        }
        std::cout << "bind success" << std::endl;

        int n1 = ::listen(_listenfd,10);
        if (n1 == 0)
        {
            std::cout << "listen success" << std::endl;
        }
    }

    void Start()
    {
        sockaddr_in peer;
        socklen_t len = sizeof(peer);
        _socketfd = accept(_listenfd,CONV(&peer),&len);
        if (_socketfd < 0)
        {
            Die(ACCEPT_ERROR);
        }
        InetAddr tt(peer);
	std::cout << "get a new connection: " << tt.netaddr() << std::endl;
        char buffer[1024];
        while(true)
        {
            int n = ::read(_socketfd,buffer,sizeof(buffer));
            if (n > 0)
            {
                buffer[n] = 0;
                InetAddr cli(peer);
                std::cout << cli.netaddr() << "says# " << buffer << std::endl;

                std::string client = "echo server says# ";
                client += buffer;
                ::write(_socketfd,client.c_str(),client.size());
            }
        }
    }

    ~ServerTcp() {}
private:
    uint16_t _port;
    int _listenfd;
    int _socketfd;
};
